﻿using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using SIGEB.Prototipo.Control;
using System.Windows.Forms;
using SIGEB.Modelo.moduloUsuarios;
using System.Collections.Generic;
using SIGEB.Modelo.moduloPerfiles;
using System;
using SIGEB.Modelo;

namespace SIGEB.Prototipo.Vista.moduloTipoUsuario
{
    public partial class frm_tipoUsuarios : frm_IMEC
    {
        #region "constructores"

        public frm_tipoUsuarios()
        {
            InitializeComponent();
            inicializarComponentes();
        }

        public frm_tipoUsuarios(controlPrincipal cp)
            : base(cp)
        {
            InitializeComponent();
            asignarUI(this.Controls);
            inicializarComponentes();

        }

        /// <summary>
        /// inicia los diferentes componentes, se debe llamar para cualquier
        /// constructor
        /// </summary>
        private void inicializarComponentes()
        {
            base.dgv_busqueda = this.dgv_listado;
            estado = new estadoVentanaImec();
            
        }

        #endregion

        #region "eventos"

        private void txb_busqueda_TextChanged(object sender, EventArgs e)
        {
            lbl_mensajes.Text = string.Empty;
        }

        private void txb_busqueda_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode.Equals(Keys.Enter))
            {
                if (txb_busqueda.Text.Equals(string.Empty))
                {
                    if (modoB)
                    {
                        modoB = false;
                        finalizarBusqueda();
                    }
                }
                else
                {
                    modoB = true;
                    string[] v = new string[] { "columna1", "columna2" };
                    if (iniciarBusqueda(txb_busqueda.Text, v).Equals(0))
                    {
                        mostrarInfo("La búsqueda no generó ningún resultado.");
                        modoB = false;
                        finalizarBusqueda();
                    }
                }
            }
        }

        private void txt_nombre_TextChanged(object sender, EventArgs e)
        {
            //borrarError(txt_nombre);
        }

        private void txt_descr_TextChanged(object sender, EventArgs e)
        {
            //borrarError(txt_descr);
        }

        private void cbx_tipoPerfiles_SelectedIndexChanged(object sender, EventArgs e)
        {
            //borrarError(cbx_tipoPerfiles);
        }

        /// <summary>
        /// se llama cuando se realiza una actualización de la base de datos
        /// en esta misma instancia
        /// </summary>
        /// <param name="referencia"></param>
        /// <param name="e"></param>
        public override void actualizar(object referencia, bibliotecaObservador.EventoActualizacion e)
        {
            int numConjunto = (int)referencia;
            if (numConjunto == conjuntoBase.CONJTIPOSPERFIL)
            {
                cargarDatosTipoPerfil();
            }
            else if (numConjunto == conjuntoBase.CONJTIPOUSUARIO)
            {
                cargarDatosTipoUsuario();
            }
        }

        private void cargarDatosTipoPerfil()
        {
            try
            {
                llenearTipoPerfiles(cp.ctrlTipoUsuario.obtenerTiposPerfiles());
            }
            catch (Exception ex)
            {
                ventanaError(ex.Message);
            }
        }

        private void cargarDatosTipoUsuario()
        {
            try
            {
                datosActuales = cp.ctrlTipoUsuario.obtenerTiposUsuario();
                llenarDTGTipoUsr(datosActuales);
            }
            catch (Exception ex)
            {
                ventanaError(ex.Message);
            }
        }
        
        /// <summary>
        /// se llama cada vez que se abre la ventana y recibe
        /// los parámetros
        /// </summary>
        /// <param name="arg">se usa para que se le pase cualquier tipo de objeto al abrir la ventana</param>
        public override void hacerVisible(object[] arg)
        {

            base.hacerVisible(arg);
            PasarConsulta();
            cargarDatosTipoPerfil();
            cargarDatosTipoUsuario();
            actualizaControles();
            
        }

        /// <summary>
        /// se activa cuando se selecciona alguna fila del DGV
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgv_listado_SelectionChanged(object sender, EventArgs e)
        {
            if (estado.CONSULTANDO())
            {
                tipoUsrActual = getSelected();
                escribirTipoUsuario();
            }
            actualizaControles();
        }

        #endregion

        #region "validación"
    
        #endregion

        #region "captura"

        /// <summary>
        /// obtiene el id del tipo perfil que fue seleccionado
        /// del combo box del los tipos de perfil
        /// </summary>
        /// <returns></returns>
        private string getTipoPerfilSelected()
        {
            try
            {
                return ((comboBoxItem)cbx_tipoPerfiles.SelectedItem).id;
            }
            catch
            {
                return null;
            }
        }
        
        /// <summary>
        /// obtiene un tipoUsuario creado con los campos de texto y combo box que hayan en el momento
        /// </summary>
        /// <returns></returns>
        private tipoUsuario getFromFields()
        {
            return new tipoUsuario(null, txt_nombre.Text, txt_descr.Text, getTipoPerfilSelected());
        }

        /// <summary>
        /// obtieneel tipoUsuario que se seleccionó del DGV
        /// </summary>
        /// <returns></returns>
        private tipoUsuario getSelected()
        {
            tipoUsuario nuevo = null;
            try
            {
                dgv_listado.Rows[dgv_listado.SelectedCells[0].RowIndex].Selected = true;
                String codigo = dgv_listado.SelectedRows[0].Cells[0].Value.ToString();
                if (codigo != null)
                {
                    nuevo = getTipoUsuario(codigo);
                    if (nuevo != null)
                    {
                        tipoUsrActual = nuevo;
                    }
                }
            }
            catch
            {

            }
            return nuevo;
        }

        /// <summary>
        /// obtiene un tipoUsuario entre la lista de datosActuales
        /// </summary>
        /// <param name="codigo"></param>
        /// <returns></returns>
        private tipoUsuario getTipoUsuario(String codigo)
        {
            if (datosActuales != null)
            {
                foreach (tipoUsuario act in datosActuales)
                {
                    if (act.codTipoUsuario == codigo)
                    {
                        return act;
                    }
                }
            }
            return null;
        }

        #endregion

        #region "métodos"

        /// <summary>
        /// escribe tipoUsrActual en los campos de texto
        /// </summary>
        private void escribirTipoUsuario()
        {
            if (tipoUsrActual != null)
            {
                txt_nombre.Text = tipoUsrActual.nombre;
                txt_descr.Text = tipoUsrActual.descripcion;
                seleccionarTipoPerfil(tipoUsrActual.idTipoPerfil);
            }
            else
            {
                limpiarCampos();
            }
        }

        /// <summary>
        /// en el combo box selecciona el nombre del tipoPerfil que se le indique
        /// de acuerdo con el parámetro que debe ser el código del tipoPerfil
        /// </summary>
        /// <param name="p"></param>
        private void seleccionarTipoPerfil(string p)
        {
            foreach (object act in cbx_tipoPerfiles.Items)
            {
                if (((comboBoxItem)act).id == p)
                {
                    cbx_tipoPerfiles.Text = ((comboBoxItem)act).mostrar;
                }
            }
        }

        /// <summary>
        /// lista en el ComboBox la lista que reciba por parámetro.
        /// Solamente listará los nombres del tipoPerfil
        /// </summary>
        /// <param name="tipoPerfiles"></param>
        private void llenearTipoPerfiles(LinkedList<tipoPerfil> tipoPerfiles)
        {
            cbx_tipoPerfiles.Items.Clear();
            if (tipoPerfiles != null)
            {
                foreach (tipoPerfil act in tipoPerfiles)
                {
                    cbx_tipoPerfiles.Items.Add(new comboBoxItem(act.codTipoPerfil, act.nombre));
                }
            }
        }

        /// <summary>
        /// llena las columnas de acuerdo con los campos del tipoPerfil
        /// </summary>
        private void llenarColumnas()
        {
            dgv_listado.Columns.Clear();
            dgv_listado.Columns.Add("columna0", "Id");
            dgv_listado.Columns[0].Visible = false;
            dgv_listado.Columns.Add("columna1", "Nombre");
            dgv_listado.Columns.Add("columna2", "Descripción");
        }

        /// <summary>
        /// lista en el DGV la lista de tipoUsuarios recibda
        /// </summary>
        /// <param name="tiposUsuarios"></param>
        private void llenarDTGTipoUsr(LinkedList<tipoUsuario> tiposUsuarios)
        {
            llenarColumnas();
            if (tiposUsuarios != null)
            {
                foreach (tipoUsuario act in tiposUsuarios)
                {
                    dgv_listado.Rows.Add(act.codTipoUsuario, act.nombre, act.descripcion);
                }
            }
        }

        #endregion

        #region "controles"


        /// <summary>
        /// actualiza el estado de los botones de acuerdo con el estado que
        /// se encuentra la ventana(en modo consulta, edición o agregando nuevo)
        /// </summary>
        private void actualizarBotones()
        {
            if (estado.AGREGANDO())
            {
                btn_Nuevo.Enabled = false;
                btn_eliminar.Enabled = false;
                btn_guardar.Enabled = true;
                btn_editar.Enabled = false;
                btn_cancelar.Enabled = true;
            }
            else if (estado.EDITANDO())
            {
                btn_Nuevo.Enabled = false;
                btn_eliminar.Enabled = true && cp.usuarioActualPuede(acciones.TIPUSR_ELIMINAR);
                btn_guardar.Enabled = true;
                btn_editar.Enabled = false;
                btn_cancelar.Enabled = true;
            }
            else if (estado.CONSULTANDO())
            {
                btn_Nuevo.Enabled = true && cp.usuarioActualPuede(acciones.TIPUSR_AGREGAR);
                btn_eliminar.Enabled = tipoUsrActual != null && cp.usuarioActualPuede(acciones.TIPUSR_ELIMINAR);
                btn_guardar.Enabled = false;
                btn_editar.Enabled = tipoUsrActual != null && cp.usuarioActualPuede(acciones.TIPUSR_AGREGAR);
                btn_cancelar.Enabled = false;
            }

        }

        /// <summary>
        /// actualiza el estado de los campos de texto y CBX de acuerdo con el estado que
        /// se encuentra la ventana(en modo consulta, edición o agregando nuevo)
        /// </summary>
        private void actualizarCampos()
        {
            if (estado.AGREGANDO())
            {
                txt_nombre.Enabled = true;
                txt_descr.Enabled = true;
                cbx_tipoPerfiles.Enabled = true;
            }
            else if (estado.EDITANDO())
            {
                txt_nombre.Enabled = true;
                txt_descr.Enabled = true;
                cbx_tipoPerfiles.Enabled = true;
            }
            else if (estado.CONSULTANDO())
            {
                txt_nombre.Enabled = false;
                txt_descr.Enabled = false;
                cbx_tipoPerfiles.Enabled = false;
            }
        }

        /// <summary>
        /// actualiza el estado del tipoUsrActua en caso de que haya
        /// alguno seleccionado del DGV
        /// </summary>
        private void actualizarTipoUsrActual()
        {
            if (estado.CONSULTANDO()&&tipoUsrActual!=null)
            {
                tipoUsrActual = getSelected();
                escribirTipoUsuario();                
            }
        }

        /// <summary>
        /// actualiza los campos y los botones
        /// </summary>
        private void actualizaControles()
        {
            actualizarBotones();
            actualizarCampos();
            actualizarTipoUsrActual();
        }

        /// <summary>
        /// limpia los campos de texto
        /// </summary>
        private void limpiarCampos()
        {
            borrarError(txt_nombre);
            borrarError(txt_descr);
            borrarError(cbx_tipoPerfiles);
            lbl_mensajes.Text = "";

            txt_descr.Text = null;
            txt_nombre.Text = null;
            cbx_tipoPerfiles.Text = null;
        }

        #endregion

        #region "acciones"

        private void PasarAgregar()
        {
            if (estado.CONSULTANDO())
            {
                tipoUsrActual = null;
                estado.agregar();
                actualizaControles();
                limpiarCampos();
            }
        }

        private void PasarConsulta()
        {
            bool modoConsulta = true;
            if (estado.AGREGANDO())
            {
                modoConsulta = confirmarOperacion("No se ha terminado de agregar el elemento");
            }
            else if (estado.EDITANDO())
            {
                modoConsulta = confirmarOperacion("Si continúa no se guardarán los cambios hechos");
            }
            if (modoConsulta)
            {
                estado.consultar();
                actualizaControles();
                if (tipoUsrActual == null)
                {
                    limpiarCampos();
                }
                else
                {
                    escribirTipoUsuario();
                }
            }
        }

        private void PasarEditar()
        {
            if (estado.CONSULTANDO() && getSelected() != null && tipoUsrActual != null)
            {
                estado.editar();
                actualizaControles();
            }
        }

        private void agregarNuevoTipoUsuario()
        {
            tipoUsuario nuevo = getFromFields();
            try
            {
                if (nuevo != null && cp.ctrlTipoUsuario.camposAgregarValidos(nuevo.nombre, nuevo.descripcion, nuevo.idTipoPerfil))
                {
                    cp.ctrlTipoUsuario.crearTipoUsuario(nuevo.nombre, nuevo.descripcion, nuevo.idTipoPerfil);
                }
                estado.consultar();
                limpiarCampos();
                actualizaControles();
            }
            catch (Exception e)
            {
                ventanaError(e.Message);
            }     
        }

        private void modificarTipoUsuario()
        {
            tipoUsuario nuevo = getFromFields();
            try
            {
                if (nuevo != null && tipoUsrActual != null && cp.ctrlTipoUsuario.camposModificarValidos(nuevo.nombre, nuevo.descripcion, nuevo.idTipoPerfil))
                {
                    cp.ctrlTipoUsuario.modificarTipoUsuario(new tipoUsuario(tipoUsrActual.codTipoUsuario, nuevo.nombre, nuevo.descripcion, nuevo.idTipoPerfil));
                }
                estado.consultar();
                limpiarCampos();
                actualizaControles();
            }
            catch (Exception e)
            {
                ventanaError(e.Message);
            }
        }

        private void eliminarTipoUsuarioSelected()
        {
            try
            {
                if (estado.EDITANDO())
                {
                    cp.ctrlTipoUsuario.eliminarTipoUsuario(tipoUsrActual);
                }
                else if (estado.CONSULTANDO() && tipoUsrActual != null)
                {
                    cp.ctrlTipoUsuario.eliminarTipoUsuario(tipoUsrActual);
                }
            }
            catch (Exception ex)
            {
                ventanaError(ex.Message);
            }
        }

        #endregion

        #region "métodos botones"

        private void btn_Nuevo_Click(object sender, EventArgs e)
        {
            PasarAgregar();
        }

        private void btn_cancelar_Click(object sender, EventArgs e)
        {
            PasarConsulta();
        }

        private void btn_guardar_Click(object sender, EventArgs e)
        {
            if (txt_nombre.Text.Equals(string.Empty))
            {
                setError(txt_nombre, "Ingrese un nombre de Tipo de Usuario.");
            }
            else
            {
                borrarError(txt_nombre);
            }
            //if (txt_descr.Text.Equals(string.Empty))
            //{
            //    setError(txt_descr, "Ingrese una descripción.");
            //    return;
            //}
            if (cbx_tipoPerfiles.SelectedIndex.Equals(-1))
            {
                setError(cbx_tipoPerfiles, "Seleccione un Tipo Perfil.");
            }
            else
            {
                borrarError(cbx_tipoPerfiles);
            }
            if(erp_error.GetError(txt_nombre).Equals(string.Empty)
                //&& erp_error.GetError(txt_descr).Equals(string.Empty) 
                && erp_error.GetError(cbx_tipoPerfiles).Equals(string.Empty)){
                if (estado.AGREGANDO())
                {
                    agregarNuevoTipoUsuario();
                }
                if (estado.EDITANDO())
                {
                    modificarTipoUsuario();
                }
            }
        }

        private void btn_editar_Click(object sender, EventArgs e)
        {
            PasarEditar();
        }

        private void btn_eliminar_Click(object sender, EventArgs e)
        {
            eliminarTipoUsuarioSelected();
        }


        #endregion

        #region "atributos"

        LinkedList<tipoUsuario> datosActuales;
        tipoUsuario tipoUsrActual;

        #endregion
    }
}